package com.sq.common.utils.request;

import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.sq.common.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Collections;
import java.util.Map;
import java.util.Objects;

import static cn.hutool.core.net.NetUtil.isUnknown;


/**
 * 工具类
 *
 */
public class RequestUtil {

    private static final String User_Agent = "User-Agent";


    public static String getRequestIp(){
        HttpServletRequest request = getRequest();

        return getIpAddr(request);
    }

    public static String getIpAddr(HttpServletRequest request)
    {
        if (request == null)
        {
            return "unknown";
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Real-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getRemoteAddr();
        }

        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
    }

    /**
     * 从多级反向代理中获得第一个非unknown IP地址
     *
     * @param ip 获得的IP地址
     * @return 第一个非unknown IP地址
     */
    public static String getMultistageReverseProxyIp(String ip)
    {
        // 多级反向代理检测
        if (ip != null && ip.indexOf(",") > 0)
        {
            final String[] ips = ip.trim().split(",");
            for (String subIp : ips)
            {
                if (false == isUnknown(subIp))
                {
                    ip = subIp;
                    break;
                }
            }
        }
        return StringUtils.substring(ip, 0, 255);
    }

    /**
     * 获取所有的请求参数
     * @return
     */
    public static Map<String, String[]> getRequestParam(){
        HttpServletRequest request = getRequest();
        Map<String, String[]> parameterMap = request.getParameterMap();
        return Collections.unmodifiableMap(parameterMap);
    }

    public static String getRequestUrl() {
        return getRequest().getRequestURI();
    }

    public static String getUserOsName(){
        HttpServletRequest request = getRequest();
        if (Objects.isNull(request)){
            return "";
        }
        String uaStr = request.getHeader(User_Agent);
        return uaStr;
    }

    public static String getBrowserName() {
        HttpServletRequest request = getRequest();
        String uaStr = request.getHeader(User_Agent);
        UserAgent ua = UserAgentUtil.parse(uaStr);
        return ua.getBrowser().toString();
    }

    public static String getBrowserVersion(){
        HttpServletRequest request = getRequest();
        String uaStr = request.getHeader(User_Agent);
        UserAgent ua = UserAgentUtil.parse(uaStr);
        return ua.getVersion();
    }

    public static String getUserRequestTool(){
        String browserName = getBrowserName();
        String browserVersion = getBrowserVersion();
        return browserName + "-" + browserVersion;
    }



    public static String getUserHeaderValue(HttpServletRequest request,String headerName){
        return request.getHeader(headerName);
    }


    /**
     * 获取request
     */
    public static jakarta.servlet.http.HttpServletRequest getRequest() {
        try {
            jakarta.servlet.http.HttpServletRequest request = getRequestAttributes().getRequest();
            return request;
        } catch (Exception e) {
            return null;
        }
    }

    public static jakarta.servlet.http.HttpServletResponse getResponse() {
        try {
            jakarta.servlet.http.HttpServletResponse response = getRequestAttributes().getResponse();
            return response;
        } catch (Exception e) {
            return null;
        }
    }




    public static ServletRequestAttributes getRequestAttributes() {
        try {
            RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
            return (ServletRequestAttributes) attributes;
        } catch (Exception e) {
            return null;
        }
    }




}